const {
  app,
  router
} = require('./connect');
const https = require('https');
const http = require('http');
const fs = require('fs');
const path = require('path')
const bodyParser = require('body-parser')
const expressJwt = require('express-jwt')

const user = require('./api/user')
const posts = require('./api/posts')
const auth = require('./api/auth')
const upload = require('./api/upload');
const menu = require('./api/menu');
const vben = require('./api/vbenUser');
const { getToken } = require('./token/token');
const { PRIVATE_KEY } = require('./utils/constant');

// 请求拦截
app.all('*', (req, res, next) => {
  next();
})

//解析token获取用户信息
app.use((req, res, next) => {
  //注意此处token；authorization设置要与设置一致否则可能出现token为空
  var token = req.headers['authorization'];
  if (token === undefined) {
    return next();
  } else {
    getToken(`${token}`).then((data) => {
      // @ts-ignore
      req.data = data;             //解析成功后返回设置基本信息（通过req.data判断是否过期）
      return next();
    }).catch((error) => {
      return next();
    })
  }
});

//验证token是否过期并规定那些路由不需要验证
app.use(expressJwt({
  secret: PRIVATE_KEY,
  algorithms: ['HS256']
}).unless({
  //不需要验证的接口名称
  path: ['/user/login',
    '/user/register',
    '/vben/register',
    '/vben/login',
    '/menu',
    '/vben/sendMsg',
    '/vben/test'
  ]
}))

app.use('/user', user);
app.use('/posts', posts);
app.use('/auth', auth);
app.use('/', vben);
app.use('/', upload);
app.use('/menu', menu);

// 处理表单提交，对应请求头application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({
  extended: false // 为true时将使用qs库处理数据，通常不需要
}))

// 处理fetch请求，对应请求头application/json
app.use(bodyParser.json())


// 自定义统一异常处理中间件，需要放在代码最后
router.use((err, req, res, next) => {
  // 自定义用户认证失败的错误返回
  if (err && err.name === 'UnauthorizedError') {
    const {
      status = 401, message
    } = err;
    // 抛出401异常
    res.status(status).json({
      code: status,
      msg: 'token失效，请重新登录',
      data: null
    })
  } else {
    const {
      output
    } = err || {};
    // 错误码和错误信息
    const errCode = (output && output.statusCode) || 500;
    const errMsg = (output && output.payload && output.payload.error) || err.message;
    res.status(errCode).json({
      code: errCode,
      msg: errMsg
    })
  }
})

const privateCrt = fs.readFileSync(path.join(process.cwd(), './https/ssl.pem'), 'utf8');
const privateKey = fs.readFileSync(path.join(process.cwd(), './https/ssl.key'), 'utf8');

const httpsOption = {
  key: privateKey,
  cert: privateCrt
}

let server = process.env.NODE_ENV === 'development' ? http.createServer(app) : https.createServer(httpsOption, app);
server.listen(3333, () => {
  console.log('server is running in port 3333...', process.env.NODE_ENV == 'development')
})